package cn.bird.storm.component.jackson.response;

import cn.bird.exception.BusiException;
import cn.bird.exception.CoreStatusInfo;
import cn.bird.exception.IStatus;
import cn.hutool.core.util.StrUtil;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

import java.util.function.Supplier;

@Data
@Slf4j
public class ResponseResult<T> {
    /**
     * 状态码
     */
    private String retCode;
    /**
     * 状态说明
     */
    private String retMsg;
    private T data;
    /**
     * 流程编码
     */
    private String traceId;

    public String getTraceId() {
        if (StrUtil.isBlank(traceId)) {
            return MDC.get("traceId");
        }
        return traceId;
    }

    /**
     * 成功有返回值
     */
    public static ResponseResult<Object> byStatus(IStatus iStatus){
        ResponseResult<Object> responseResult = new ResponseResult<>();
        responseResult.setRetCode(iStatus.getCode());
        responseResult.setRetMsg(iStatus.getMessage());
        return responseResult;
    }

    /**
     * 成功有返回值
     */
    public static <T> ResponseResult<T> success(T t){
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setRetCode(CoreStatusInfo.SUCCESS.getCode());
        responseResult.setRetMsg(CoreStatusInfo.SUCCESS.getMessage());
        responseResult.setData(t);
        return responseResult;
    }

    /**
     * 成功无返回值
     */
    public static ResponseResult<Void> success() {
        ResponseResult<Void> responseResult = new ResponseResult<>();
        responseResult.setRetCode(CoreStatusInfo.SUCCESS.getCode());
        responseResult.setRetMsg(CoreStatusInfo.SUCCESS.getMessage());
        return responseResult;
    }
    /**
     * 成功无返回值 定义提示语
     */
    public static ResponseResult<Void> successWithMsg(String retMsg) {
        ResponseResult<Void> responseResult = new ResponseResult<>();
        responseResult.setRetCode(CoreStatusInfo.SUCCESS.getCode());
        responseResult.setRetMsg(retMsg);
        return responseResult;
    }

    /**
     * 成功无返回值 定义提示语
     */
    public static <T> ResponseResult<T> successWithMsg(T t,String retMsg) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setRetCode(CoreStatusInfo.SUCCESS.getCode());
        responseResult.setRetMsg(retMsg);
        responseResult.setData(t);
        return responseResult;
    }

    /**
     * 失败默认提示码--指定提示语句
     */
    public static <T> ResponseResult<T> fail(String retMsg) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setRetCode(CoreStatusInfo.BUSINESS_ERROR.getCode());
        responseResult.setRetMsg(retMsg);
        return responseResult;
    }

    /**
     * 失败默认提示码--指定code,msg和返回值
     */
    public static <T> ResponseResult<T> fail(String code,String retMsg,T data) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setRetCode(code);
        responseResult.setRetMsg(retMsg);
        responseResult.setData(data);
        return responseResult;
    }

    public static <T> ResponseResult<T> fail(String code,String retMsg) {
        ResponseResult<T> responseResult = new ResponseResult<>();
        responseResult.setRetCode(code);
        responseResult.setRetMsg(retMsg);
        return responseResult;
    }

    public void assertSuccess() {
        if (!CoreStatusInfo.SUCCESS.getCode().equals(this.retCode)) {
            throw new BusiException(retCode, retMsg);
        }
    }

    public boolean checkSuccess() {
        return CoreStatusInfo.SUCCESS.getCode().equals(this.retCode);
    }

    public T assertSuccessAndGet() {
        if (!CoreStatusInfo.SUCCESS.getCode().equals(this.retCode)) {
            throw new BusiException(retCode, retMsg);
        }
        return data;
    }
    /**
     * 如果调用失败，执行默认函数，返回默认值
     */
    public T getDataOrElse(Supplier<T> supplier) {
        if (!CoreStatusInfo.SUCCESS.getCode().equals(this.retCode)) {
            log.error("执行出错：{}---{}", retCode, retMsg);
            return supplier.get();
        }
        return data;
    }

    /**
     * 如果调用失败，直接返回默认值
     */
    public T getDataOrElseGet(T defValue) {
        if (!CoreStatusInfo.SUCCESS.getCode().equals(this.retCode)) {
            log.error("执行出错：{}---{}", retCode, retMsg);
            return defValue;
        }
        return data;
    }

    /**
     * 如果调用失败，直接返回默认值
     */
    public void ifErrorLog(String msg) {
        if (!CoreStatusInfo.SUCCESS.getCode().equals(this.retCode)) {
            log.error((StrUtil.isBlank(msg) ? "执行出错" : msg) + "：{}---{}", retCode, retMsg);
        }
    }
}
